﻿
Imports System.Threading

Namespace destructor
    Public Module destructor
        Public Const maxDestructTime As UInt64 = 1000 * 60 * 16
        Public Const minDestructTime As UInt64 = 1000 * 7.5
        Public Const defaultDestructTime As UInt64 = 1000 * 60
        Public destructTime As UInt64 = defaultDestructTime
        Public Const defaultFullCollectRound As Int32 = 16
        Public fullCollectRound As Int32 = defaultFullCollectRound
        Private btIndex As Int64

        Public Sub destruct()
            GC.Collect()
        End Sub

        Friend Sub destructCaller()
            Static lastcall As Int64 = 0
            If lastcall = 0 Then
                lastcall = Now.seconds()
            End If
#If Not (PocketPC OrElse Smartphone) Then
            Static i As Int32 = 0
#End If
            If Now.seconds() - lastcall >= destructTime Then
                lastcall = Now.seconds()
#If Not (PocketPC OrElse Smartphone) Then
                If Environment.WorkingSet() >= (totalPhysicalMemory() >> 1) Then
                    destructTime >>= 2
                ElseIf Environment.WorkingSet() >= (totalPhysicalMemory() >> 2) Then
                    destructTime >>= 1
                ElseIf Environment.WorkingSet() < (totalPhysicalMemory() >> 6) Then
                    destructTime <<= 1
                End If
#End If
                If destructTime < minDestructTime Then
                    destructTime = minDestructTime
                ElseIf destructTime > maxDestructTime Then
                    destructTime = maxDestructTime
                End If
#If Not (PocketPC OrElse Smartphone) Then
                i += 1
                If i >= fullCollectRound Then
                    i = 0
                    'collect memory of non-refered objects in all generations
                    GC.Collect()
                Else
                    'collect memory of non-refered objects in generations older than half of maxgeneration
                    GC.Collect(GC.MaxGeneration() >> 1)
                End If
#Else
                GC.Collect()
#End If
            End If
        End Sub

        Public Sub start()
            btIndex = queueInBackendThread(AddressOf destructCaller)
        End Sub

        Public Sub [stop]()
            removeFromBackendThread(btIndex)
        End Sub
    End Module
End Namespace
